// 强类型语言的作用, 可以直接声明或着说出函数或者变量的类型. 
(function () {
    function sendMsg(str) {
        return "hello" + str;
    }
    var text = 'world';
    // let text = [1, 2, 3, 4]
    console.log(sendMsg(text));
    console.log('000000');
    // 类只能进行变量的定义. 
    var User = /** @class */ (function () {
        function User() {
        }
        return User;
    }());
    // null、undefined
    // 将null、undefined传递给其他类型是可以的. 
    var u;
    var num = u;
    var str = u;
    // void值不能传给其他基础类型变量. ts自动检测, 会编译时候就报错. 
    // js里面是不会报错的. 
    // let v:void
    // let num1:number = v
    // let str1:string = v
    // 还有空格是不会被加载进js代码里的. 
    var a = true;
    // let b:number = a 
    // 不能把number类型的变量赋值给boolean类型
    // new Boolean()返回的是一个对象, 不是boolean值
    // let isDone:boolean = new Boolean(1); // 编译报错, 不能将Boolean类型给boolean.
    //  这里的Boolean(1)是返回的一个boolean值. 
    var idDone = Boolean(1);
    // 这样是可以的, 将String类型的值给String类型. 
    var isString = new String("111");
    // 数值类型
    var decLiteral = 6;
    // ts, js中只有一个数值对象, 没有java那样的多个数值, int、float、double. 
    var decimal = 6.66;
    var hexLiteral = 0xf00d;
    // ES6 中的二进制表示法
    var binaryLiteral = 10;
    // ES6 中的八进制表示法
    var octalLiteral = 484;
    var notANumber = NaN;
    var infinityNumber = Infinity;
    // void, 空值, 没有什么用, 因为只能将null、undefined赋值给他.
    // null、undefined是所有基础类型的子类, 所以, 可以赋值给任何类型. 
    // 基本数据类型包括了: 
    // null、undefined、boolean、number、string、object
    // array、function、map等... 
    // 没有给类型的变量, 是默认的any类型, 后来可以赋任何值 
    var anyVarible;
    // string
    anyVarible = '12';
    // number
    anyVarible = 12;
    // js如果初始化了, 但是没有给初始化类型, 那么声明的类型就是const, 不让改动的类型. 
    // ts就不让没有声明类型的变量存在. 这里会报错的. 
    // constVarible = '12';
    // 和变量一样, 如果, 没有给返回值类型, 那么可以返回各种, 和any一样. 
    function sendResult(string) {
        // return '1111'
        return 111;
    }
    // 类型推断: 就是在初始化没有声明变量类型, 但是给了初始化值了, 那么, 就会推断该变量就是这个类型的, 和范型有一点像. 
    // <T> 类型是不确定的, 只有在调用的使用, 才知道是什么类型. 
    // 断言
    function getLength2(param) {
        // 直接利用length属性来判断是否有是string类型, 如果是, 那么就将length输出
        // 如果不是, 就先转成toString() 转成string类型的数据. 
        if (param.length) {
            return param.length;
        }
        else {
            return param.toString().length;
        }
    }
    console.log('多个string1长度', getLength2('1111111111111'));
    console.log('多个number1长度', getLength2(1111111111111));
    // 联合类型
    function getLength(params) {
        return params.toString().length;
    }
    // 这样两者是可以实现输出长度的, 但是, 如果本身是string类型了, 那么, 就不必要进行toString(), 
    // 类型断言就是告诉编译器, 我自己知道我在干嘛. 
    console.log(getLength(123));
    console.log(getLength('123'));
    // 类型断言
    function getLength1(params) {
        // 告诉编译器, 我现在就是在string类型的参数上进行操作. 
        if (params.length)
            return params.length;
        //这里告诉编译器, 我现在就是在number类型的参数上进行操作. 
        else
            return params.toString().length;
    }
    // 这里将tom规定为Person类型, 如果没有完全继承Person的属性和行为, 就会编译报错
    var tom = {
        name: 'tom',
        age: 12
    };
    // 多于接口属性怎么写: 
    // 少了接口里面的addr也是可以的.但是, 不知道后来的对象属性怎么实现, 所以很可能要写多个`?`可缺省类型. 
    var tomo = {
        name: "tomo",
        age: 111
    };
    var tomot = {
        name: 'tomot',
        age: 12,
        addr: '上海市浦东新区' // 任意属性. 
    };
    var tommot = {
        id: 12,
        name: 'tommot',
        age: 12
    };
    console.log(tommot);
    // Cannot assign to 'id' because it is a read-only property.
    // 不能赋值给只读属性, property
    // tommot.id = 12
    /**
     * 数组的定义: 数组定义的方法:
     * 1. [类型+方括号]
     * 2. 范型
     */
    var arr = [1, 3, 4, 5];
    //  在定义的时候, 进行了类型的声明, 后续添加的数据就只能相同类型. 
    arr[arr.length] = 12;
    // 给number类型的数组, 添加了非number类型的数据, 就会导致编译时报错. 
    //  arr[arr.length + 1] = 'aaa'
    var anyArr = ['111', 12, '122'];
    // 还可以像解构赋值那样, 对不同位置的进行分别声明变量类型. 
    var anArr = [1, '11', 1];
    // 数组范型
    // 范型是在定义函数、接口或者类的时候, 不预先指定具体的类型, 而是在使用的时候再指定类型的一种特性. 
    var arr2 = [1, 2, 3, 4, 5];
    // 不指定范型的类型, 只能在定义的方法的时候使用, 
    // 这里面的T指的是, 传递进来的参数的类型. 可以根据参数类型自动转换. 
    function createArray(length, value) {
        // 这里面的result的类型也必须要和传递进来的数据类型是一样的. 
        var result = [];
        for (var i = 0; i < length; i++) {
            result[i] = value;
        }
        return result;
    }
    // 生成多个一样的数据, 但是他们的数据类型是一样的, 不过, 在使用之前, 任何类型都是可以的. 
    // 生成string类型的数组. 
    console.log(createArray(3, 'bob'));
    // 生成number类型的数组.  
    console.log(createArray(3, 12));
    // 也可以传多个不同类型的变量
    function returnVar(params) {
        return [params[0], params[1]];
    }
    /**
     * 范型约束: 在函数内部使用范型变量的时候, 由于不知道, 他会传进来什么类型的数据, 所以不能随意操作它的属性或者方法.
     */
    // 这样的方法, 必须使用的是
    function logginIdentity(param) {
        //   type T 没有办法判断是否有方法里面有的属性. 
        //  console.log(param.length);
        return param;
    }
    /**
     *
     * 类数组: 不是数组, 只是类似数组,由K V组成, 但是, 没有length等属性.
     */
    function argu(param) {
        console.log('arguments', arguments);
        var arr = [1, 2, 3, 4];
        console.log('arr type', typeof arguments == "string");
        //   这里的arguments是一个对象, 不是array
        console.log('typeOf', typeof arguments);
    }
    argu(1111111);
    function reverse(x) {
        if (typeof x === 'number')
            return Number(x.toString().split('').join);
        //   join 是数组的方法, 所以, 使用.split('')将其分开成数组,再使用数组的reverse()方法. 
        else if (typeof x === 'string')
            return x.split('').reverse().join('');
    }
    console.log(reverse(1));
    // 必须完全实现Photo接口里面的属性. 
    var photo = {
        price: 12,
        size: 11,
        weight: 10
    };
    console.log(photo);
    // let alarm:Alarm = {
    //     price: 11
    //     // weight:11,
    //     // alert(x:string, y:number) :string
    // }
    console.dir(Number);
    var Items = [
        {
            id: 4,
            name: 'bob',
            age: 21
        },
        {
            id: 3,
            name: 'bob',
            age: 21
        },
        {
            id: 2,
            name: 'bob',
            age: 21
        },
        {
            id: 1,
            name: 'bob',
            age: 21
        },
        {
            id: 2,
            name: 'bob',
            age: 21
        },
        {
            id: 2,
            name: 'bob',
            age: 21
        },
    ];
    Items.forEach(function (item) {
        console.log(item);
        if (item.id === 1) {
            console.log('1');
            return;
        }
    });
    var tmo = {
        // 类中, 还是需要有逗号的. 
        name: 'tmo',
        age: 12,
        sayHi: function () { return '90'; }
    };
    var arr11 = {
        // 类中, 还是需要有逗号的. 
        name: 'tmo',
        age: 12,
        sayHi: function () { return '90'; }
    };
    /**
     * 函数声明
     */
    function sum(x, y) {
        return x + y;
    }
    console.log('1+2', sum('1', 2)); // 输出结果: '12'
    console.log('Number(1)+2', sum(Number('1'), 2)); // 输出结果: '12'
    console.log('1 + 2', sum(1, 2)); // 输出结果:  3
    //  function sum(x:number, y: number) {
    //  }
})();
